package com.pethospital.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pethospital.dto.MedicalRecordDTO;
import com.pethospital.dto.VaccineDTO;
import com.pethospital.entity.Appointment;
import com.pethospital.entity.MedicalRecord;
import com.pethospital.entity.Pet;
import com.pethospital.entity.Staff;
import com.pethospital.entity.Vaccine;
import com.pethospital.exception.BusinessException;
import com.pethospital.mapper.MedicalRecordMapper;
import com.pethospital.mapper.PetMapper;
import com.pethospital.mapper.VaccineMapper;
import com.pethospital.service.AppointmentService;
import com.pethospital.service.MedicalRecordService;
import com.pethospital.service.PetService;
import com.pethospital.service.StaffService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;

/**
 * 健康档案服务实现类
 */
@Slf4j
@Service
public class MedicalRecordServiceImpl extends ServiceImpl<MedicalRecordMapper, MedicalRecord> implements MedicalRecordService {

    @Resource
    private MedicalRecordMapper medicalRecordMapper;

    @Resource
    private VaccineMapper vaccineMapper;

    @Resource
    private PetMapper petMapper;

    @Resource
    private PetService petService;

    @Resource
    private StaffService staffService;
    
    @Resource
    private AppointmentService appointmentService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long addMedicalRecord(MedicalRecordDTO medicalRecordDTO, Long staffId) {
        log.info("添加健康档案, 医生ID: {}, 数据: {}", staffId, medicalRecordDTO);

        // 获取宠物信息
        Pet pet = petService.getById(medicalRecordDTO.getPetId());
        if (pet == null) {
            throw new BusinessException("宠物不存在");
        }

        // 获取医生信息
        Staff staff = staffService.getById(staffId);
        if (staff == null) {
            throw new BusinessException("医生信息不存在");
        }

        // 获取预约信息
        Appointment appointment = appointmentService.getById(medicalRecordDTO.getAppointmentId());
        if (appointment == null) {
            throw new BusinessException("预约信息不存在");
        }
        
        // 检查预约状态是否为已确认状态
        if (appointment.getStatus() != 1 && appointment.getStatus() != 2) {
            throw new BusinessException("只能为已确认或已完成的预约创建健康档案");
        }
        
        // 检查是否是本医生的预约
        if (!appointment.getStaffId().equals(staffId)) {
            throw new BusinessException("无权为该预约创建健康档案");
        }
        
        // 检查是否已经有健康档案
        MedicalRecord existingRecord = getMedicalRecordByAppointmentId(medicalRecordDTO.getAppointmentId());
        if (existingRecord != null) {
            throw new BusinessException("该预约已存在健康档案");
        }

        // 创建健康档案
        MedicalRecord medicalRecord = new MedicalRecord();
        BeanUtils.copyProperties(medicalRecordDTO, medicalRecord);
        
        // 设置就诊时间，若DTO中无就诊时间则使用当前时间
        if (medicalRecord.getVisitTime() == null) {
            medicalRecord.setVisitTime(LocalDateTime.now());
        }

        // 设置医生和创建时间等信息
        medicalRecord.setStaffId(staffId);
        medicalRecord.setCreateTime(LocalDateTime.now());
        medicalRecord.setUpdateTime(LocalDateTime.now());

        // 保存健康档案
        save(medicalRecord);
        
        // 更新预约关联的医疗记录ID
        appointment.setMedicalRecordId(medicalRecord.getId());
        appointmentService.updateById(appointment);
        
        log.info("健康档案创建成功，ID：{}", medicalRecord.getId());
        return medicalRecord.getId();
    }

    @Override
    public List<MedicalRecord> getPetMedicalRecords(Long petId) {
        log.info("获取宠物健康档案列表, 宠物ID: {}", petId);
        
        // 检查宠物是否存在
        Pet pet = petService.getById(petId);
        if (pet == null) {
            throw new BusinessException("宠物不存在");
        }

        // 查询宠物所有健康档案
        LambdaQueryWrapper<MedicalRecord> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(MedicalRecord::getPetId, petId)
                .orderByDesc(MedicalRecord::getVisitTime);

        List<MedicalRecord> records = list(queryWrapper);
        fillMedicalRecordsExtraInfo(records);
        
        return records;
    }

    @Override
    public Page<MedicalRecord> getPetMedicalRecordsPage(Long petId, int page, int size) {
        log.info("获取宠物健康档案分页, 宠物ID: {}, 页码: {}, 每页大小: {}", petId, page, size);
        
        // 检查宠物是否存在
        Pet pet = petService.getById(petId);
        if (pet == null) {
            throw new BusinessException("宠物不存在");
        }

        // 分页查询健康档案
        LambdaQueryWrapper<MedicalRecord> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(MedicalRecord::getPetId, petId)
                .orderByDesc(MedicalRecord::getVisitTime);

        Page<MedicalRecord> recordPage = page(new Page<>(page, size), queryWrapper);
        fillMedicalRecordsExtraInfo(recordPage.getRecords());
        
        return recordPage;
    }

    @Override
    public MedicalRecord getMedicalRecord(Long id) {
        log.info("获取健康档案详情, ID: {}", id);

        // 查询健康档案
        MedicalRecord medicalRecord = getById(id);
        if (medicalRecord == null) {
            return null;
        }

        // 填充附加信息
        fillMedicalRecordExtraInfo(medicalRecord);

        return medicalRecord;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateMedicalRecord(Long id, MedicalRecordDTO medicalRecordDTO, Long staffId) {
        log.info("更新健康档案, ID: {}, 医生ID: {}, 数据: {}", id, staffId, medicalRecordDTO);

        // 获取健康档案
        MedicalRecord medicalRecord = getById(id);
        if (medicalRecord == null) {
            throw new BusinessException("健康档案不存在");
        }

        // 检查是否是本医生创建的健康档案
        if (!medicalRecord.getStaffId().equals(staffId)) {
            throw new BusinessException("无权修改该健康档案");
        }

        // 检查宠物是否存在
        Pet pet = petService.getById(medicalRecordDTO.getPetId());
        if (pet == null) {
            throw new BusinessException("宠物不存在");
        }

        // 设置健康档案信息
        BeanUtils.copyProperties(medicalRecordDTO, medicalRecord, "id", "staffId", "createTime");
        
        // 保留原医生ID
        medicalRecord.setUpdateTime(LocalDateTime.now());

        return updateById(medicalRecord);
    }

    @Override
    public Page<MedicalRecord> getStaffMedicalRecords(Long staffId, int page, int size) {
        log.info("获取医生创建的健康档案, 医生ID: {}, 页码: {}, 每页大小: {}", staffId, page, size);

        // 查询医生创建的健康档案
        LambdaQueryWrapper<MedicalRecord> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(MedicalRecord::getStaffId, staffId)
                .orderByDesc(MedicalRecord::getCreateTime);

        Page<MedicalRecord> recordPage = page(new Page<>(page, size), queryWrapper);
        fillMedicalRecordsExtraInfo(recordPage.getRecords());
        
        return recordPage;
    }

    @Override
    public MedicalRecord getMedicalRecordByAppointmentId(Long appointmentId) {
        log.info("根据预约ID查询健康档案, 预约ID: {}", appointmentId);

        // 先查询预约信息
        Appointment appointment = appointmentService.getById(appointmentId);
        if (appointment == null) {
            return null;
        }
        
        // 如果预约没有关联的医疗记录ID，直接返回null
        if (appointment.getMedicalRecordId() == null) {
            return null;
        }
        
        // 查询健康档案
        MedicalRecord medicalRecord = getById(appointment.getMedicalRecordId());
        if (medicalRecord != null) {
            fillMedicalRecordExtraInfo(medicalRecord);
            medicalRecord.setAppointmentId(appointmentId);
        }
        
        return medicalRecord;
    }
    
    /**
     * 填充健康档案列表的额外信息
     */
    private void fillMedicalRecordsExtraInfo(List<MedicalRecord> records) {
        if (records == null) {
            return;
        }
        
        for (MedicalRecord record : records) {
            fillMedicalRecordExtraInfo(record);
        }
    }
    
    /**
     * 填充单个健康档案的额外信息
     */
    private void fillMedicalRecordExtraInfo(MedicalRecord record) {
        if (record == null) {
            return;
        }
        
        // 填充宠物名称
        if (record.getPetId() != null) {
            Pet pet = petService.getById(record.getPetId());
            if (pet != null) {
                record.setPetName(pet.getName());
            }
        }
        
        // 填充医生名称
        if (record.getStaffId() != null) {
            Staff staff = staffService.getById(record.getStaffId());
            if (staff != null) {
                record.setStaffName(staff.getName());
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long addVaccineRecord(VaccineDTO vaccineDTO, Long userId) {
        // 验证宠物是否存在且属于当前用户
        Pet pet = petMapper.selectById(vaccineDTO.getPetId());
        if (pet == null) {
            throw new BusinessException("宠物不存在");
        }
        if (!pet.getUserId().equals(userId)) {
            throw new BusinessException("无权操作此宠物");
        }

        // 创建疫苗记录
        Vaccine vaccine = new Vaccine();
        vaccine.setPetId(vaccineDTO.getPetId());
        vaccine.setVaccineName(vaccineDTO.getVaccineName());
        vaccine.setVaccineTime(vaccineDTO.getVaccineTime());
        vaccine.setNextTime(vaccineDTO.getNextTime());
        vaccine.setStatus(1); // 已接种
        vaccine.setRemark(vaccineDTO.getRemark());
        vaccine.setCreateTime(LocalDateTime.now());
        vaccine.setUpdateTime(LocalDateTime.now());
        vaccineMapper.insert(vaccine);
        return vaccine.getId();
    }

    @Override
    public List<Vaccine> getVaccineRecordsByPetId(Long petId) {
        LambdaQueryWrapper<Vaccine> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Vaccine::getPetId, petId)
                    .orderByDesc(Vaccine::getVaccineTime);
        return vaccineMapper.selectList(queryWrapper);
    }
} 